package com.my.stock.core;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import org.zeromq.ZMQ;

import util.JavaFile;

public class ShowMeTheMoney4 {

	public static BlockingQueue<String> subQueue = new ArrayBlockingQueue<String>(10240000);

	public Thread tickSUBThread = new Thread(new Runnable() {

		public void run() {
			ZMQ.Context context = ZMQ.context(1);
			ZMQ.Socket s = context.socket(ZMQ.SUB);
			s.connect("tcp://127.0.0.1:5556");
			s.subscribe("".getBytes());
			while (true) {
				byte recStr[] = s.recv();
				if (recStr == null) {
					continue;
				}
				String sg = "";
				try {
					sg = new String(recStr, "gb2312");
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
				if (subQueue.offer(sg)) {

				} else {
					System.out.println("SUB ERROR!!!!");
				}
			}
		}

	});
	public Thread tickThread = new Thread(new Runnable() {

		public void run() {
			while (true) {
				String sg = "";
				try {
					sg = subQueue.take();
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}

				if (sg.equals("")) {
					continue;
				}

//					System.out.println(sg);
				if (sg.startsWith("errorOrder")) {

					System.out.println("下单错误！！！" + sg);

				} else if (sg.startsWith("queryOrder")) {
					System.out.println(sg);
					String code = sg.split(",")[1];
					Product p = productMap.get(code);
					if (p == null || Integer.parseInt(sg.split(",")[3]) == 0) {
						continue;
					}
					p.setOwnPosition(p.getOwnPosition() + Integer.parseInt(sg.split(",")[3]));
					p.setOrderPrice(
							Double.parseDouble(sg.split(",")[4]) / Integer.parseInt(sg.split(",")[3]) / p.getUnit());
					System.out.println(p.getOrderPrice());
				} else if (sg.startsWith("OKOrder")) {

					// 订单提交成功
					if (sg.split(",")[3].equals("3")) {
						// 撤单成功
						if (sg.split(",")[4].equals("5")) {
//							String code = sg.split(",")[1];
//							Product p = productMap.get(code);
//							if (p == null) {
//								continue;
//							}
//
//							if (sg.split(",")[8].equals("0")) {
//								p.setPoolInsertOrderNum(
//										p.getPoolInsertOrderNum() - Integer.parseInt(sg.split(",")[11]));
//							} else {
//								p.setPoolStopOrderNum(p.getPoolStopOrderNum() - Integer.parseInt(sg.split(",")[11]));
//							}
//							p.setDone(false);
//							System.out.println("撤单成功！！！" + sg);
						} else if (sg.split(",")[4].equals("0")) {
							// 成交
//							String code = sg.split(",")[1];
//							Product p = productMap.get(code);
//
//							if (p == null) {
//								System.out.println(code);
//								continue;
//							}
//
//							if (sg.split(",")[8].equals("0")) {
//								// 开仓
//								p.setPoolInsertOrderNum(p.getPoolInsertOrderNum() - Integer.parseInt(sg.split(",")[2]));
//
//							} else {
//								// 平仓
//								p.setPoolStopOrderNum(p.getPoolStopOrderNum() - Integer.parseInt(sg.split(",")[2]));
//								p.setCloseOrderTime(System.currentTimeMillis());
//								p.setStopLossPrice(0);
//							}
//							System.out.println("订单成交！！！" + sg);
						} else if (sg.split(",")[4].equals("3")) {

						}
					}

				} else {

					long log = DateUtil.getNowDateTimeT(sg.split(",")[6]);
					String code = sg.split(",")[0];
					if (log > 2000) {
						System.out.println("警告超时！！！" + log + "ms");
					}
					processTick(sg, code);

				}

			}
		}

	});

	private boolean closeCondition(Product p, double buyPrice, double sellPrice) {
		Date d = new Date();

		if (d.getHours() == 14 && d.getMinutes() >= 50) {
			return true;
		} else {
			return false;
		}

	}

	public void processTick(String tick, String code) {

		Thread tradeThread = new Thread(new Runnable() {
			public void run() {
				try {
					JavaFile.writefile("c:\\tick\\" + code + ".txt", tick + "\r\n");

//					if(code.equals("i2501")) {
//						String x = dataProcess.buyOrSell(tick);
//						if(x.equals("")) {
//							return;
//						}
//						String result = bayesBuy.main(x.split(",")[0] + "," + x.split(",")[1] + "," + x.split(",")[2] + ","
//								+ x.split(",")[3] + "," + x.split(",")[4] + "," + x.split(",")[5] + "," + x.split(",")[6] + ","
//								+ x.split(",")[7] + "," + x.split(",")[8] + "," + x.split(",")[9] + "," + x.split(",")[10] + ","
//								+ x.split(",")[11] + "," + x.split(",")[12]);
					//
//						if (result.equals("+++++++")) {
//							System.out.println("买入");
//						} else {
//							System.out.println("不再买入");
//						}
//						String result = bayesSell.main(x.split(",")[0] + "," + x.split(",")[1] + "," + x.split(",")[2] + ","
//								+ x.split(",")[3] + "," + x.split(",")[4] + "," + x.split(",")[5] + "," + x.split(",")[6] + ","
//								+ x.split(",")[7] + "," + x.split(",")[8] + "," + x.split(",")[9] + "," + x.split(",")[10] + ","
//								+ x.split(",")[11] + "," + x.split(",")[12]);
//						if (result.equals("+++++++")) {
//							System.out.println("卖出");
//						} else {
//							System.out.println("不再卖出");
//						}
//					}

				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		tradeThread.start();

	}

	double lastvol = 0;
	double lastinterest = 0;

	public void processTick1(String tick) {

		String code = tick.split(",")[0];
		Product p = productMap.get(code);
		if (p != null) {
//			System.out.println(tick);

			double buyPrice = Double.parseDouble(tick.split(",")[3]);
			double sellPrice = Double.parseDouble(tick.split(",")[2]);
			double buyVolume = Double.parseDouble(tick.split(",")[8]);
			double sellVolume = Double.parseDouble(tick.split(",")[7]);

			double turnover = Double.parseDouble(tick.split(",")[9]);
			double volume = Double.parseDouble(tick.split(",")[10]);

			double openInterest = Double.parseDouble(tick.split(",")[11]);
			double preOpenInterest = Double.parseDouble(tick.split(",")[12]);
			double averagePrice = Double.parseDouble(tick.split(",")[13]);
			double lPrice = Double.parseDouble(tick.split(",")[14]);
			double totalPrice = averagePrice * volume / 1000;
			double averagePrice1 = (turnover - p.getLastTurnover()) / (volume - p.getLastVolume());
//			System.out.println("成交量" + (volume - p.getLastVolume()) + "   成交金额" + (turnover - p.getLastTurnover())
//					+ " 平均金额" + averagePrice + " 持仓量" + openInterest + " 上次持仓量" + preOpenInterest);

			double t = (turnover - p.getLastTurnover());
			double currentVolume = volume - p.getLastVolume();

			double aPrice = t / currentVolume / p.getUnit();
			double rPrice = Math.rint(aPrice);

			double t1 = rPrice * (volume - p.getLastVolume()) * p.getUnit();
			double tb = p.getLastBuyPrice() * (volume - p.getLastVolume()) * p.getUnit();
			double ts = p.getLastSellPrice() * (volume - p.getLastVolume()) * p.getUnit();

			double fixnum = Math.abs((t - t1)) / p.getUnit();

			int stepMove = 0;
			double sellV = 0;
			double buyV = 0;

			if (p.getLastVolume() != 0 && currentVolume > 0) {
				System.out.print("rPrice:" + rPrice);
				boolean moveUpDirection = false;

				double sellPriceMove = Math.abs(sellPrice - p.getLastSellPrice());
				double buyPriceMove = Math.abs(buyPrice) - p.getLastBuyPrice();

				System.out.print(
						" getLastBuyPrice:" + p.getLastBuyPrice() + " getLastSellPrice:" + p.getLastSellPrice() + "  ");

				if (Math.abs(rPrice - p.getLastBuyPrice()) < Math.abs(rPrice - p.getLastSellPrice())) {
					// 成交更接近买盘
//					System.out.print("  成交更接近买盘");
					moveUpDirection = false;
					stepMove = (int) (buyPriceMove / p.getUnit());
				} else if (Math.abs(rPrice - p.getLastSellPrice()) < Math.abs(rPrice - p.getLastBuyPrice())) {
					// 成交更接近卖盘
//					System.out.print("  成交更接近卖盘");
					moveUpDirection = true;
					stepMove = (int) (sellPriceMove / p.getUnit());

				} else {
//					System.out.print("买卖盘相等");
				}

				if (fixnum > 0) {
					// 需要修正买卖盘

//					System.out.println("fixnum:" + fixnum + " currentVolume:" + currentVolume + "  ls:"
//							+ (p.getLastSellPrice() - sellPrice) + "  lb:" + (p.getLastBuyPrice() - buyPrice));

					if (stepMove >= 2) {
						// 移动了2个价位以上
						if (moveUpDirection) {
							buyV = currentVolume;
						} else {
							sellV = currentVolume;
						}
					} else if (stepMove == 0 || stepMove == 1) {

						if (moveUpDirection) {
							// 上升
							buyV = currentVolume - fixnum;
							sellV = fixnum;
						} else {
							// 下降
							sellV = currentVolume - fixnum;
							buyV = fixnum;

						}
					} else {
						System.out.println("warning!!!!!!!!4");
					}

				} else {
					// 无需修正

					if (moveUpDirection) {
						buyV = currentVolume;
					} else {
						sellV = currentVolume;
					}
				}

				p.getBuyTU().insertData(buyV);
				p.getSellTU().insertData(sellV);

				p.setTotalBuyVolume(p.getTotalBuyVolume() + buyV);
				p.setTotalSellVolume(p.getTotalSellVolume() + sellV);

				double oneMinsCountb = p.getBuyTU().getOneMinsCount();
				double threeMinsCountb = p.getBuyTU().getThreeMinsCount();
				double fiveMinsCountb = p.getBuyTU().getFiveMinsCount();
				double TenMinsCountb = p.getBuyTU().getTenMinsCount();
				double oneMinsCounts = p.getSellTU().getOneMinsCount();
				double threeMinsCounts = p.getSellTU().getThreeMinsCount();
				double fiveMinsCounts = p.getSellTU().getFiveMinsCount();
				double TenMinsCounts = p.getSellTU().getTenMinsCount();

				System.out.println((moveUpDirection ? "up" : "down") + " " + stepMove + " " + " fix:" + fixnum + "  "
						+ currentVolume + "总买盘:" + (p.getTotalBuyVolume() - p.getTotalSellVolume()) + " 1min:"
						+ (oneMinsCountb - oneMinsCounts) + " threeMinsCount:" + (threeMinsCountb - threeMinsCounts)
						+ " fiveMinsCount:" + (fiveMinsCountb - fiveMinsCounts) + " TenMinsCount:"
						+ (TenMinsCountb - TenMinsCounts));

				if (p.getStrategy().equals("buy") && p.getOwnPosition() < p.getMaxOrderNum()) {
					if (oneMinsCountb - oneMinsCounts < p.getTriggerVolume()) {
						p.setTriggerCount(p.getTriggerCount() + 1);
					} else if (oneMinsCountb - oneMinsCounts > 0) {
						p.setTriggerCount(0);
					} else if (oneMinsCountb - oneMinsCounts > p.getTriggerVolume() * -1) {
						cancelOrder(p.getCode(), 0);
					}

					if (p.getStopMovingVolume() == 0) {
						p.setStopMovingVolume((oneMinsCountb - oneMinsCounts));
					} else if (p.getStopMovingVolume() < (oneMinsCountb - oneMinsCounts)) {
						// 止跌回升
						p.setStopMovingCount(p.getStopMovingCount() + 1);
					} else if (p.getStopMovingVolume() > (oneMinsCountb - oneMinsCounts)) {
						// 继续下跌
						p.setStopMovingVolume((oneMinsCountb - oneMinsCounts));
						p.setStopMovingCount(0);
					}

				}

				if (p.getStrategy().equals("sell") && p.getOwnPosition() < p.getMaxOrderNum()) {
					if (oneMinsCountb - oneMinsCounts > p.getTriggerVolume()) {
						p.setTriggerCount(p.getTriggerCount() + 1);
					} else if (oneMinsCountb - oneMinsCounts < 0) {
						p.setTriggerCount(0);
					} else if (oneMinsCountb - oneMinsCounts < p.getTriggerVolume() * -1) {
						cancelOrder(p.getCode(), 0);
					}

					if (p.getStopMovingVolume() == 0) {
						p.setStopMovingVolume((oneMinsCountb - oneMinsCounts));
					} else if (p.getStopMovingVolume() > (oneMinsCountb - oneMinsCounts)) {
						// 止升下降
						p.setStopMovingCount(p.getStopMovingCount() + 1);
					} else if (p.getStopMovingVolume() < (oneMinsCountb - oneMinsCounts)) {
						// 创新高
						p.setStopMovingVolume((oneMinsCountb - oneMinsCounts));
						p.setStopMovingCount(0);
					}
				}

				if (p.getTriggerCount() > p.getTriggerNeed() && p.getStopMovingCount() > p.getStopMovingNeed()) {
//					insertOrder(p.getCode(), buyPrice, sellPrice);

					System.out.println("下单");
				}

			}

			p.setLastBuyVolum(buyVolume);
			p.setLastSellVolum(sellVolume);
			p.setLastTurnover(turnover);
			p.setLastVolume(volume);
			p.setLastAveragePrice(averagePrice);
			p.setLastTotalPrice(totalPrice);
			p.setLastBuyPrice(buyPrice);
			p.setLastSellPrice(sellPrice);
			p.setLastlPrice(lPrice);
		}

	}

	// 检查下单条件
	private String checkInsertOrder(String code, double buyPrice, double sellPrice) {
		Date d = new Date();
		Product p = productMap.get(code);

		if (d.getHours() == 14 && d.getMinutes() > 30 || d.getHours() == 15) {
			return "";
		} else {
			if (p.getPoolInsertOrderNum() == 0 && p.getCloseOrderTime() == 0 && p.getOrderTime() == 0) {

				if (buyPrice < p.getOpenBuyPrice() - p.getMinStep() * p.getStopLossStep()) {
					return "sell";
				}
				if (sellPrice > p.getOpenSellPrice() + p.getMinStep() * p.getStopLossStep()) {
					return "buy";
				}

			} else {
				return "";
			}
		}
		return "";
	}

	private void insertOrder(String code, double buyPrice, double sellPrice) {
		Product p = productMap.get(code);
		p.setPoolInsertOrderNum(p.getMaxOrderNum());
		p.setOwnPosition(p.getMaxOrderNum());

		p.setOpenBuyPrice(sellPrice);
		p.setOpenSellPrice(buyPrice);
		p.setOrderTime(System.currentTimeMillis());
		String order = p.getStrategy() + "," + code + ",1," + sellPrice + "," + buyPrice + "\0";
		signalQueue.offer(order);
//		String order1 = "sell," + code + "," + p.getPoolInsertOrderNum() + "," + sellPrice + "," + buyPrice + "\0";
//		signalQueue.offer(order1);

	}

	private void closePositon(String code, double buyPrice, double sellPrice) {
		System.out.print("止盈" + code);
		Product p = productMap.get(code);
		String type = p.getTradeType();
		if (type.equals("buy")) {
			type = "sell";
		} else {
			type = "buy";
		}

		String order = type + "," + code + "," + p.getOwnPosition() + "," + sellPrice + "," + buyPrice + "\0";

		signalQueue.offer(order);

	}

	// 停损
	private void stopLoss(String code, double buyPrice, double sellPrice) {
		System.out.print("停损" + code + "！！！");
		Product p = productMap.get(code);
		String type = p.getTradeType();
		if (type.equals("buy")) {
			type = "sell";
		} else {
			type = "buy";
		}
		String order = type + "," + code + "," + p.getOwnPosition() + "," + sellPrice + "," + buyPrice + "\0";
		signalQueue.offer(order);
	}

	private void cancelOrder(String code, int combOffsetFlag) {

		Product p = productMap.get(code);
		if (p.getOrderTime() > 0) {
			String type = "cancel";
			String or = "";
			if (combOffsetFlag == 0) {
				if (p.getInsertOrderRef().equals("")) {
					return;
				} else {
					or = p.getInsertOrderRef();
					p.setInsertOrderRef("");
				}
			} else {
				if (p.getStopOrderRef().equals("")) {
					return;
				} else {
					or = p.getStopOrderRef();
					p.setStopOrderRef("");
				}
			}
			String order = type + "," + p.getExchangeID() + "," + p.getParkedOrderID() + "," + p.getInstrumentID() + ","
					+ or + "\0";
			cancelList.add(order);
		}

	}

	private static Map<String, Product> productMap = new HashMap<String, Product>();

	public static BlockingQueue<String> signalQueue = new ArrayBlockingQueue<String>(1024);

	public static List<String> cancelList = new ArrayList<String>();

	Thread tradeThread = new Thread(new Runnable() {
		public void run() {
			ZMQ.Context context = ZMQ.context(1);
			ZMQ.Socket s = context.socket(ZMQ.REQ);
			s.connect("tcp://*:5557");
//			signalQueue.offer("queryOrder,a");
			while (true) {
				String trade;
				try {
					trade = signalQueue.take();
					System.out.println(trade);
					s.send(trade.getBytes(), 0);
					s.recv(0);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}
		}
	});

	private Bayes bayesBuy;
	private Bayes bayesSell;
	private DataProcess dataProcess;

	public ShowMeTheMoney4(String fileBuy, String fileSell, double unit, double minPriceStep) {
//		String dataBuy;
//		try {
//			dataBuy = JavaFile.readfileToStringN(fileBuy);
//			bayesBuy = new Bayes(dataBuy);
//			String dataSell = JavaFile.readfileToStringN(fileSell);
//			bayesSell = new Bayes(dataSell);
//			dataProcess = new DataProcess(100, 0.5);
//		} catch (IOException e) {
//			e.printStackTrace();
//		}

	}

	public static void main(String[] args) throws IOException {
		List<String> config = JavaFile.readfile("d:\\show.txt");
		for (String c : config) {
			Product p = new Product();
			p.setCode(c.split(",")[0]);
			p.setContractName(c.split(",")[1]);
			p.setMaxOrderNum(Integer.parseInt(c.split(",")[3]));
			p.setMinStep(Double.parseDouble(c.split(",")[4]));
			p.setUnit(Integer.parseInt(c.split(",")[5]));
			p.setStrategy(c.split(",")[6]);
			p.setStopLossStep(Integer.parseInt(c.split(",")[7]));
			p.setTriggerVolume(Double.parseDouble(c.split(",")[8]));
			p.setTriggerNeed(Integer.parseInt(c.split(",")[9]));
			p.setStopMovingNeed(Integer.parseInt(c.split(",")[10]));
			productMap.put(c.split(",")[0], p);
			System.out.println(p.getContractName());
		}

		ShowMeTheMoney4 s = new ShowMeTheMoney4("d:\\i2501buy.txt", "d:\\i2501sell.txt", 100, 0.5);

		s.tickThread.start();
		s.tickSUBThread.start();
		s.tradeThread.start();

	}
}
